#!/usr/bin/python
# -*- coding: utf-8 -*-

#-------------------------------------------------
#Create At: 2009-2-4 上午09:31:18 
#Create By: Fla.sam
#
#DESC: 
#
#-------------------------------------------------

from django.contrib.auth import REDIRECT_FIELD_NAME
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from urllib import quote
from django.contrib.auth.models import User, Group
from django.conf import settings


def user_passes_test_with_403(test_func, login_url=None):
    '''
         检查用户权限
    @param test_func:
    @param login_url:
    '''
    """
    Decorator for views that checks that the user passes the given test.
    
    Anonymous users will be redirected to login_url, while users that fail
    the test will be given a 403 error.
    """
    if not login_url:
        login_url = settings.LOGIN_URL
    def _dec(view_func):
        def _checklogin(request, *args, **kwargs):
            if test_func(request.user):
                return view_func(request, *args, **kwargs)
            elif not request.user.is_authenticated():
                return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, quote(request.get_full_path())))
            else:
                resp = render_to_response('403.html', context_instance=RequestContext(request))
                resp.status_code = 403
                return resp
        _checklogin.__doc__ = view_func.__doc__
        _checklogin.__dict__ = view_func.__dict__
        return _checklogin
    return _dec

def permission_required_with_403(perm, login_url=None):
    '''
         检查用户是否拥有指定的权限
    @param perm:
    @param login_url:
    '''
    """
    Decorator for views that checks whether a user has a particular permission
    enabled, redirecting to the log-in page or rendering a 403 as necessary.
    """
    return user_passes_test_with_403(lambda u: u.has_perm(perm), login_url=login_url)

def active_login_required_with_403(login_url=None):
    '''
         检查用户的 active 状态,  
    @param login_url:
    '''
    return user_passes_test_with_403(lambda u: u.is_authenticated() and u.is_active, login_url=login_url)

def group_required_with_403(group_name, login_url=settings.LOGIN_URL):
    '''
         检查用户是否在指定的组内
    @param group_name:
    @param login_url:
    '''
    def wrap(view_func):
        def in_group(request, *args, **kwargs):
            if request.user.is_anonymous():
                resp = render_to_response('403.html', context_instance=RequestContext(request))
                resp.status_code = 403
                return resp
            try:
                group = request.user.groups.get(name=group_name)
            except Group.DoesNotExist: #@UndefinedVariable
                resp = render_to_response('403.html', context_instance=RequestContext(request))
                resp.status_code = 403
                return resp
            else:
                return view_func(request, *args, **kwargs)

        return in_group
    return wrap


def groups_required_with_403(groups_name, login_url=None):
    '''
         检查用户属组是否在指定的多个组内
    @param groups_name:
    @param login_url:
    '''
    def wrap(view_func):
        def in_groups(request, *args, **kwargs):
            if request.user.is_anonymous():
                resp = render_to_response('403.html', context_instance=RequestContext(request))
                resp.status_code = 403
                return resp
            for group_name in groups_name:
                try:
                    group = request.user.groups.get(name=group_name)
                except Group.DoesNotExist: #@UndefinedVariable
                    group = False
                if group:
                    return view_func(request, *args, **kwargs)
            # at last no one group found, return 403 page
            resp = render_to_response('403.html', context_instance=RequestContext(request))
            resp.status_code = 403
            return resp
        return in_groups
    return wrap
    


